<!--
 * @Author: zhaoti
 * @Date: 2022-06-13 17:26:14
 * @LastEditors: wanglianxin
 * @LastEditTime: 2023-09-21 18:01:14
 * @FilePath: \standard-check\src\components\PublicForm\PublicForm.vue
 * @Description: 公共表单组件
-->
<template>
  <div class="i-form">
    <a-form
      :class="classForm"
      :form="form"
      autocomplete="off"
      :labelAlign="labelAlign"
      :layout="formData.layout"
      v-if="iformModel.length"
      :key="formKey"
      @submit="handleSubmit"
    >
      <template v-for="(item, index) in iformModel">
        <a-form-item
          :label="isLabel(item)"
          :style="{ display: item.type === 'hidden' ? 'none' : '' }"
          :class="{ 'inline-input': item.type === 'inlineInput' && !item.allowNull }"
          :colon="false"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
          :key="index"
          v-if="!item.itemHidden"
        >
          <a-input
            :style="{ width: item.width || '100%' + '!important' }"
            :disabled="!item.allowModify"
            :class="item.key"
            @blur="item.blur($event, iformModel, formData, index)"
            @change="handleInputChange($event, item)"
            @pressEnter="nextFocus(index)"
            allowClear
            v-decorator="[
              item.key,
              {
                initialValue: item.value && String(item.value) != 'null' ? item.value : '',
                rules: [
                  { required: !item.allowNull, message: '请输入' + item.name },
                  {
                    pattern: item.limitType === 'reg' ? item.limit : null,
                    message: item.limitTips,
                  },
                ],
              },
            ]"
            type="passward"
            v-if="checkInpuShow(item)"
            :ref="item.key + index + '-ele'"
          />
          <a-input
            :style="{ width: item.width || '100%' + '!important' }"
            :disabled="!item.allowModify"
            :class="item.key"
            @blur="item.blur($event, iformModel, formData, index)"
            @change="handleInputChange($event, item)"
            @pressEnter="nextFocus(index)"
            allowClear
            v-decorator="[
              item.key,
              {
                initialValue: item.value && String(item.value) != 'null' ? item.value : '',
                rules: [
                  { required: !item.allowNull, message: '请输入' + item.name },
                  {
                    pattern: item.limitType === 'reg' ? item.limit : null,
                    message: item.limitTips,
                  },
                ],
              },
            ]"
            :type="item.type"
            v-if="item.type === 'hidden'"
            :ref="item.key + index + '-ele'"
          />
          <a-input
            :style="{ width: item.width || '100%' + '!important' }"
            :disabled="!item.allowModify"
            :class="item.key"
            @blur="item.blur($event, iformModel, formData, index)"
            @pressEnter="nextFocus(index)"
            allowClear
            v-decorator="[
              item.key,
              {
                initialValue: item.value && String(item.value) != 'null' ? item.value : '',
                rules: [
                  { required: !item.allowNull, message: '请输入' + item.name },
                  {
                    pattern: item.limitType === 'reg' ? item.limit : null,
                    message: item.limitTips,
                  },
                ],
              },
            ]"
            autocomplete="new-password"
            type="password"
            v-if="item.type === 'password'"
            :ref="item.value + index + '-ele'"
          />
          <a-input-group compact v-if="item.type === 'groupInput'">
            <a-input
              :style="{ width: '70%' + '!important' }"
              :class="item.key"
              :disabled="!item.allowModify"
              @blur="item.blur($event, iformModel, formData, index)"
              @pressEnter="nextFocus(index)"
              v-decorator="[
                item.key,
                {
                  initialValue: item.value && String(item.value) != 'null' ? item.value : '',
                  rules: [
                    { required: !item.allowNull, message: '请输入' + item.name },
                    {
                      pattern: item.limitType === 'reg' ? item.limit : null,
                      message: item.limitTips,
                    },
                  ],
                },
              ]"
              type="passward"
              :ref="item.key + index + '-ele'"
            />
            <a-tooltip placement="top">
              <a-button
                :style="{ width: item.groupButton.width }"
                :type="item.groupButton.type"
                @click="handleInputGroup(item.groupButton.value)"
                >{{ item.groupButton.text }}</a-button
              >
            </a-tooltip>
          </a-input-group>
          <a-input-group
            compact
            v-if="item.type === 'input' && item.key === 'rsaccno' && editRsaccno"
          >
            <a-input
              :style="{ width: '80%' + '!important' }"
              :class="item.key"
              :disabled="true"
              @blur="item.blur($event, iformModel, formData, index)"
              @pressEnter="nextFocus(index)"
              v-decorator="[
                item.key,
                {
                  initialValue: item.value && String(item.value) != 'null' ? item.value : '',
                  rules: [
                    { required: !item.allowNull, message: '请输入' + item.name },
                    {
                      pattern: item.limitType === 'reg' ? item.limit : null,
                      message: item.limitTips,
                    },
                  ],
                },
              ]"
              type="passward"
              :ref="item.key + index + '-ele'"
            />
            <a-tooltip placement="top">
              <template slot="title"> 修改关联账户 </template>
              <a-button style="width: 20%" @click="modifyRelation"><a-icon type="edit" /></a-button>
            </a-tooltip>
          </a-input-group>
          <!-- 选择器不需要正则校验 -->
          <a-select
            :style="{ width: item.width || '100%' + '!important' }"
            :disabled="!item.allowModify"
            :allowClear="item.allowNull"
            show-search
            option-filter-prop="children"
            :filter-option="filterOption"
            :getPopupContainer="(triggerNode) => triggerNode.parentNode"
            @blur="item.blur($event, iformModel, formData, index)"
            @select="item.select($event, iformModel, formData, index)"
            @keydown.enter.native="nextFocus(index)"
            @change="selectChange($event, item)"
            v-decorator="[
              item.key,
              {
                initialValue: item.value || item.value == 0 ? item.value : null,
                rules: [{ required: !item.allowNull, message: '请选择' + item.name }],
              },
            ]"
            v-if="item.type === 'select'"
            :ref="item.key + index + '-ele'"
            :notFoundContent="item.notFoundContent"
          >
            <a-select-option
              v-for="(kitem, kindex) in item.options"
              :value="kitem.code"
              :key="kindex"
              :title="kitem.name"
              >{{ kitem.name ? kitem.name : '     ' }}</a-select-option
            >
          </a-select>
          <a-date-picker
            :style="{ width: item.width || '100%' + '!important' }"
            :disabled="!item.allowModify"
            :format="format"
            :showToday="false"
            :disabled-date="(value) => disabledDate(value, item)"
            v-decorator="[
              item.key,
              {
                initialValue: item.value ? initMoment(item) : null,
                rules: [
                  { type: 'object', required: !item.allowNull, message: '请选择' + item.name },
                ],
              },
            ]"
            v-if="item.type === 'date'"
            :ref="item.key + index + '-ele'"
          />
          <a-radio-group
            v-if="item.type === 'radio'"
            :ref="item.key + index + '-ele'"
            v-decorator="[
              item.key,
              {
                initialValue: item.value ? item.value : '',
                rules: [
                  { required: !item.allowNull, message: '请选择' + item.name },
                  {
                    pattern: item.limitType === 'reg' ? item.limit : null,
                    message: item.limitTips,
                  },
                ],
              },
            ]"
            :disabled="!item.allowModify"
          >
            <a-radio :value="kitem.code" v-for="(kitem, kindex) in item.options" :key="kitem.code">
              {{ kitem.name }}
            </a-radio>
          </a-radio-group>
          <a-checkbox-group
            v-if="item.type === 'checkout'"
            :ref="item.key + index + '-ele'"
            v-decorator="[
              item.key,
              {
                initialValue: item.value ? item.value : [],
                rules: [{ required: !item.allowNull, message: '请选择' + item.name }],
              },
            ]"
            :disabled="!item.allowModify"
          >
            <template v-for="(kitem, kindex) in item.options">
              <a-checkbox :value="kitem.code" :key="kindex">{{ kitem.name }}</a-checkbox> <br />
            </template>
          </a-checkbox-group>
          <template v-if="item.type === 'inlineInput'">
            <a-form-item style="display: inline-block; width: calc(50% - 24px)">
              <a-input
                :disabled="!item.allowModify"
                :class="item.key"
                allowClear
                @blur="item.blur($event, iformModel, formData, index)"
                v-decorator="[
                  item.key,
                  {
                    initialValue: item.value && String(item.value) != 'null' ? item.value : '',
                    rules: [
                      { required: !item.allowNull, message: '请输入' + item.requiredHint },
                      {
                        pattern: item.limitType === 'reg' ? item.limit : null,
                        message: item.limitTips,
                      },
                    ],
                  },
                ]"
                :ref="item.key + index + '-ele'"
              />
            </a-form-item>
            <span
              style="
                display: inline-block;
                width: 24px;
                text-align: center;
                margin: auto 12px !important;
              "
              >——</span
            >
            <a-form-item style="display: inline-block; width: calc(50% - 24px)">
              <a-input
                :disabled="!item.inline.allowModify"
                :class="item.inline.key"
                allowClear
                v-decorator="[
                  item.inline.key,
                  {
                    initialValue:
                      item.inline.value && String(item.inline.value) != 'null'
                        ? item.inline.value
                        : '',
                    rules: [
                      {
                        required: !item.inline.allowNull,
                        message: '请输入' + item.inline.requiredHint,
                      },
                      {
                        pattern: item.inline.limitType === 'reg' ? item.inline.limit : null,
                        message: item.inline.limitTips,
                      },
                    ],
                  },
                ]"
                :ref="item.inline.key + index + '-ele'"
              />
            </a-form-item>
          </template>
        </a-form-item>
      </template>
    </a-form>
  </div>
</template>

<script>
import moment from 'moment';
import debounce from 'lodash/debounce';
import cloneDeep from 'lodash/cloneDeep';
export default {
  name: 'Iform',
  props: {
    formModel: {
      // 表单参数，必传
      type: Array,
      default: () => [],
    },
    formData: {
      // 布局参数，横向还是竖向布局
      type: Object,
      default: () => {},
    },
    labelCol: {
      //表单label宽度
      type: Object,
      default: () => {},
    },
    wrapperCol: {
      //输入框宽度
      type: Object,
      default: () => {},
    },
    format: {
      //时间格式
      type: String,
      default: 'YYYYMMDD',
    },
    classForm: {
      //表单类名
      type: String,
    },
    labelAlign: {
      type: String,
      default: 'right',
    },
  },
  data() {
    return {
      form: this.$form.createForm(this, { name: 'publicForm' }),
      iformModel: cloneDeep(this.formModel),
      currentIndex: 0,
      editRsaccno: false, //编辑关联账号
      formKey: 0, //表单key
    };
  },
  mounted() {
    this.initForm(this.iformModel);
    this.autoEmitSelectChange();
  },

  methods: {
    /**
     * @description: 初始化表单数据
     * @return {*}
     */
    initForm(list) {
      list.map((item) => {
        //给每个表单增加blur函数
        if (!item.blur) {
          item.blur = (e) => {};
        }
        //给每个表单增加change函数
        if (!item.change) {
          item.change = ($event, iformModel, formData, index) => {};
        }
        //给每个表单选择器增加select函数
        if (!item.select) {
          item.select = ($event, iformModel, formData, index) => {};
        }
      });
      this.$set(this, 'iformModel', list);
      // console.log(this.iformModel);
    },
    isLabel(item) {
      return item.type === 'hidden' ? '' : item.name;
    },
    /**
     * @description: 重置表单
     * @return {*}
     */
    resetForm() {
      this.form.resetFields();
    },
    /**
     * @description: 提交触发表单校验
     * @return {*}
     */
    handleSubmit() {
      let status = false;
      this.form.validateFields((err) => {
        status = !err;
      });
      return status;
    },
    /**
     * @description: 校验指定字段
     * @param {Array} Fields  指定字段
     * @return {*}
     */
    validateFields(Fields) {
      let status = false;
      this.form.validateFields(Fields, (err) => {
        status = !err;
      });
      return status;
    },
    /**
     * @description: 获取表单绑定值
     * @return {*}
     */
    getFormValue() {
      let values = this.form.getFieldsValue();
      if (!values.rsaccno) {
        this.iformModel.map((item) => {
          if (item.key === 'rsaccno' && item.itemHidden) {
            values.rsaccno = values.accno;
          }
        });
      }
      for (let i in values) {
        if (typeof values[i] == 'string') {
          values[i] = values[i].trim();
        }
      }
      return values;
    },
    /**
     * @description: 修改表单值
     * @param {*} value
     * @return {*}
     */
    setFormValue(value) {
      if (value.alternativeAssociatedAccount && value.alternativeAssociatedAccount.length) {
        if (!value.rsaccno) {
          this.editRsaccno = true;
        }
        delete value.alternativeAssociatedAccount;
      }
      // else {
      //   this.editRsaccno = false;
      // }
      this.form.setFieldsValue(value);
    },
    /**
     * @description: 修改单个表单配置
     * @param {*} data
     * @return {*}
     */
    setFormOpt(data) {
      let index = this.iformModel.findIndex((item) => item.key == data.key);
      if (index !== -1) {
        this.$set(this.iformModel, index, Object.assign(this.iformModel[index], data));
      }
    },
    /**
     * @description: 设置指定项聚焦
     * @param {*} item
     * @return {*}
     */
    setFormFocus(key) {
      this.iformModel.map((item, index) => {
        if (item.key === key) {
          this.currentIndex = index;
        }
      });
      this.$nextTick(() => {
        console.log(key + this.currentIndex + '-ele', this.$refs);
        this.$refs[key + this.currentIndex + '-ele'][0].focus();
      });
    },
    /**
     * @description: 禁止的日期选择
     * @param {*} value 当前选择时间
     * @return {*}
     */
    disabledDate(value, item) {
      if (!item.limit || !value) return false;
      const date = item.limit.slice(1, item.limit.length - 1).split(',');
      const startDate = date[0];
      const endDate = date[1];
      return (
        (endDate && moment(endDate).endOf('day').valueOf() < value.valueOf()) ||
        (startDate && value.valueOf() < moment(startDate).valueOf())
      );
    },
    /**
     * @description: 按下回车键 进入下个表单
     * @return {*}
     */
    nextFocus(index, e) {
      let indexKey = index + 1;
      if (this.iformModel.length !== index + 1) {
        this.$nextTick(() => {
          if (this.iformModel[indexKey].allowModify) {
            if (this.iformModel[indexKey].type === 'select') {
              this.$refs[this.iformModel[indexKey].key + indexKey + '-ele'][0].$el
                .querySelector('input')
                .click();
            } else if (this.iformModel[indexKey].type === 'date') {
              this.$refs[this.iformModel[indexKey].key + indexKey + '-ele'][0].$el
                .querySelector('input')
                .click();
            } else {
              this.$refs[this.iformModel[indexKey].key + indexKey + '-ele'][0].focus();
            }
          } else {
            this.nextFocus(indexKey);
          }
        });
      }
    },
    dataFocus(index, status) {
      this.$set(this.iformModel[index], 'backOpen', status);
      if (!status) {
        this.nextFocus(index);
      }
    },
    /**
     * @description: 选择框选中时回调
     * @param {*} index
     * @return {*}
     */
    selectedOpen(index) {
      this.hide(index);
    },
    /**
     * @description: 失去焦点之后
     * @param {*} index
     * @return {*}
     */
    hide(index) {
      this.$set(this.iformModel[index], 'backOpen', null);
    },
    /**
     * @description: 时间默认值
     * @param {*} item
     * @return {*}
     */
    initMoment(item) {
      return moment(item.value, this.format);
    },
    /**
     * @description: 检查input显示
     * @param {*} item
     * @return {*}
     */
    checkInpuShow(item) {
      if (item.type === 'input') {
        if (item.key === 'rsaccno' && this.editRsaccno) {
          return false;
        }
        return true;
      }
    },
    /**
     * @description: 修改关联关系
     * @return {*}
     */
    modifyRelation() {
      this.$emit('change', { type: 'modifyRelation' });
    },
    handleInputGroup(value) {
      this.$emit('change', { type: value });
    },
    /**
     * @description: 控制关联账号和印鉴卡号只显示一个，监控输入
     * @param {*} item
     * @return {*}
     */
    handleInputChange(e, item) {
      if (typeof e == 'string' && !e) {
        e = { target: { value: '' } };
      }
      if (item.maxLength) {
        if (e.target.value.length > item.maxLength) {
          this.$nextTick(() => {
            this.form.setFieldsValue({ [item.key]: e.target.value.substring(0, item.maxLength) });
            this.form.validateFields([item.key]);
          });
          this.checkLimitValue(item);
          return;
        }
      }
      if (item.key === 'rsaccno' || item.key === 'cardno') {
        let value = e.target.value;
        let formOpt = this.iformModel.find((items) => items.key === item.key);
        if (value.match(formOpt.limit)) {
          if (item.key === 'rsaccno') {
            this.setFormOpt({ key: 'cardno', itemHidden: true });
          } else if (item.key === 'cardno') {
            this.setFormOpt({ key: 'rsaccno', itemHidden: true });
          }
        } else {
          if (item.key === 'rsaccno') {
            this.setFormOpt({ key: 'cardno', itemHidden: false });
          } else {
            this.setFormOpt({ key: 'rsaccno', itemHidden: false });
          }
        }
      }
    },
    /**
     * @description: 防抖设置输入框长度
     * @param {*} function
     * @param {*} item
     * @return {*}
     */
    checkLimitValue: debounce(function (item) {
      this.$modalMessage.error(`${item.name}最大长度${item.maxLength}位`);
    }, 300),
    /**
     * @description: 下拉框筛选方法
     * @param {*} input
     * @param {*} option
     * @return {*}
     */
    filterOption(input, option) {
      return (
        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
      );
    },
    /**
     * @description: 验印时选中凭证类型
     * @params
     */
    selectChange(value, item) {
      //select选择触发
      this.$emit('selectChange', { [item.key]: value });
    },
    /**
     * @description: 判断表单默认数据，自动触发selectchange事件
     * @return {*}
     */
    autoEmitSelectChange() {
      this.iformModel.map((item) => {
        //判断表单数据select类型有数据时 触发selectChange事件
        if (item.type === 'select' && item.value) {
          this.$emit('selectChange', { [item.key]: item.value });
        }
      });
    },
  },
  watch: {
    formModel: {
      deep: true,
      handler(value) {
        this.iformModel = cloneDeep(value); //赋值表单刷新
        this.initForm(this.iformModel);
        this.autoEmitSelectChange();
        this.formKey++;
      },
    },
  },
};
</script>

<style lang="stylus" type="text/stylus" rel="stylesheet/stylus" scoped>

.ant-advanced-voucher-form
  >>> .ant-form-item
    margin-bottom 8px
  .inline-input >>>.ant-form-item-no-colon:before
    display: inline-block;
    margin-right: 4px;
    color: #f5222d;
    font-size: 14px;
    font-family: SimSun, sans-serif;
    line-height: 1;
    content: '*';

>>>.ant-checkbox-wrapper
  line-height 30px
</style>
